﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AEM.Data;
using Microsoft.Win32;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using AEM.Utils;
using System.Data;
using System.IO;
using AEM.Common;

namespace AEM
{
    /// <summary>
    /// FaultLog.xaml 的交互逻辑
    /// </summary>
    public partial class FaultLog : Window
    {
        public List<FaultLogItem> logList = new List<FaultLogItem>();
        public FaultLog()
        {
            InitializeComponent();
            this.TitleBar.MouseLeftButtonDown += new MouseButtonEventHandler(TitleBar_MouseLeftButtonDown);
            this.Loaded += new RoutedEventHandler(FaultLog_Loaded);
            this.btn_select.Click += new RoutedEventHandler(btn_select_Click);
            this.btn_reset.Click += new RoutedEventHandler(btn_reset_Click);
            this.datefrom.ValueChanged += new EventHandler(datefrom_SelectedDateChanged);
            this.dateto.ValueChanged += new EventHandler(dateto_SelectedDateChanged);
            this.btn_export.Click += new RoutedEventHandler(btn_export_Click);
            this.btn_histogram.Click += new RoutedEventHandler(btn_histogram_Click);
            this.btn_print.Click += new RoutedEventHandler(btn_print_Click);
        }


        void dateto_SelectedDateChanged(object sender, EventArgs e)
        {
            this.datefrom.DisplayDateEnd = this.dateto.Value;
        }

        void datefrom_SelectedDateChanged(object sender, EventArgs e)
        {
            this.dateto.DisplayDateStart = this.datefrom.Value;
        }

        void btn_reset_Click(object sender, RoutedEventArgs e)
        {
            this.liftNum.SelectedItem = null;
            this.liftSite.Content = "";
            this.datefrom.Value = DateTime.Now;
            this.dateto.Value = DateTime.Now;
            //logList = new List<FaultLogItem>();
            this.faultlogList.ItemsSource = null;
            this.faultlogList.Items.Refresh();
        }

        void FaultLog_Loaded(object sender, RoutedEventArgs e)
        {
            this.liftNum.ItemsSource = Config.LiftInftList;
            this.liftNum.Items.Refresh();
            DateTime s = DataLogHelper.GetEarliestTime();

            if (null != s && s != Convert.ToDateTime("0001-01-01 00:00:00"))
            {
                this.datefrom.DisplayDateStart = s;
                this.dateto.DisplayDateStart = s;
            }
            else
            {
                this.datefrom.DisplayDateStart = DateTime.Now;
            }
            this.datefrom.DisplayDateEnd = DateTime.Now;
            this.dateto.DisplayDateEnd = DateTime.Now;
        }


        void btn_select_Click(object sender, RoutedEventArgs e)
        {
            btn_select.IsEnabled = false;
            this.faultlogList.ItemsSource = null;
            int i = 1;
            this.msg.Text = "";
            if (null == this.datefrom.Value) { this.msg.Text = string.Format(this.TryFindResource("AskSelectOne") as string, this.TryFindResource("DateFrom") as string); btn_select.IsEnabled = true; return; }
            if (null == this.dateto.Value) { this.msg.Text = string.Format(this.TryFindResource("AskSelectOne") as string, this.TryFindResource("DateTo") as string); btn_select.IsEnabled = true; return; }
            DateTime s = this.datefrom.Value.Value;
            DateTime t = this.dateto.Value.Value;
            List<Data.DataLog.TableFaultLogRow> lists = null;
            if (null != this.liftNum.SelectedItem)
            {
                Data.Model.LiftInfo r = (Data.Model.LiftInfo)this.liftNum.SelectedItem;
                lists = DataLogHelper.GetFaultLog(r, s, t);
            }
            else
            {
                lists = DataLogHelper.GetFaultLog(s, t);
            }
            if (null != lists && null != Config.LiftInftList)
            {
                IEnumerable<ResultData> list = from row in lists
                                               join Data.Model.LiftInfo l in Config.LiftInftList
                                               on row.LN equals l.LiftNum
                                               where row.FT == (int)Data.Enum.LiftStatus.Fault
                                               || row.FT==(int)Data.Enum.LiftStatus.Fire
                                               || row.FT==(int) Data.Enum.LiftStatus.CageAlarm
                                               || row.FT == (int)Data.Enum.LiftStatus.ConverterAlarm
                                               || row.FT == (int)Data.Enum.LiftStatus.IsEarthquaked
                                               orderby row.ST
                                               select new ResultData
                                               {
                                                   RowNum = i++,
                                                   LiftNum = row.LN,
                                                   ShortName = l.ShortName,
                                                   LiftName = l.LiftSite,
                                                   FaultType = (int)row.FT,
                                                   JoinDate = row.ST
                                               };
                this.faultlogList.ItemsSource = list;
            }

            this.faultlogList.Items.Refresh();
            btn_select.IsEnabled = true;
        }

        public class ResultData
        {
            public int RowNum { get; set; }
            public int LiftNum { get; set; }
            public string ShortName { get; set; }
            public string LiftName { get; set; }
            public int FaultType { get; set; }
            public DateTime JoinDate { get; set; }
        }

        //private FaultLogItem SelectLog(Data.Model.LiftInfo r, DateTime s, DateTime t)
        //{

        //    FaultLogItem item = new FaultLogItem();
        //    item.LiftNum = r.LiftNum;
        //    item.LiftName = r.LiftSite;
        //    item.Fire = SelectCount(r.LiftNum, s, t, (int)Data.Enum.LiftStatus.Fire);
        //    item.Fault = SelectCount(r.LiftNum, s, t, (int)Data.Enum.LiftStatus.Fault);
        //    item.CageAlarm = SelectCount(r.LiftNum, s, t, (int)Data.Enum.LiftStatus.CageAlarm);
        //    item.Earthquake = SelectCount(r.LiftNum, s, t, (int)Data.Enum.LiftStatus.Earthquake);
        //    item.ConverterAlarm = SelectCount(r.LiftNum, s, t, (int)Data.Enum.LiftStatus.ConverterAlarm);
        //    return item;
        //}

        //private int SelectCount(int num, DateTime s, DateTime t, int type)
        //{
        //    int count = (from DataBase.TableFaultLogRow row in Config.dataBaseDataset.TableFaultLog.Rows
        //                where row.LiftNum == num && row.JoinDate >= s && row.JoinDate < t.AddDays(1) && row.FaultType == type
        //                select row).Count();
        //    return count;
        //}

        void btn_histogram_Click(object sender, RoutedEventArgs e)
        {

            IEnumerable<ResultData> list = (IEnumerable<ResultData>)this.faultlogList.ItemsSource;
            if (null == list || list.Count() < 1) return;
            this.Width = 1000;//635
            histogram_bg.Visibility = Visibility.Visible;

            List<KeyValuePair<string, double>> valueList = new List<KeyValuePair<string, double>>();
            //double[][] status = new double[5][];

            double count = (from ResultData r in list
                            where r.FaultType == (int)Data.Enum.LiftStatus.Fault
                            select r).Count();

            valueList.Add(new KeyValuePair<string, double>(this.TryFindResource("Fault") as string, count <= 0 ? 0 : count));
            //status[0] = new double[] { (int)Data.Enum.LiftStatus.Fault, count <= 0 ? 0 : count };

            count = 0;
            count = (from ResultData r in list
                     where r.FaultType == (int)Data.Enum.LiftStatus.Fire
                     select r).Count();
            valueList.Add(new KeyValuePair<string, double>(this.TryFindResource("Fire") as string, count <= 0 ? 0 : count));
            //status[1] = new double[] { (int)Data.Enum.LiftStatus.Fire, count <= 0 ? 0 : count };

            count = 0;
            count = (from ResultData r in list
                     where r.FaultType == (int)Data.Enum.LiftStatus.IsEarthquaked
                     select r).Count();
            valueList.Add(new KeyValuePair<string, double>(this.TryFindResource("Earthquake") as string, count <= 0 ? 0 : count));
            //status[2] = new double[] { (int)Data.Enum.LiftStatus.IsEarthquaked, count <= 0 ? 0 : count };

            count = 0;
            count = (from ResultData r in list
                     where r.FaultType == (int)Data.Enum.LiftStatus.CageAlarm
                     select r).Count();
            valueList.Add(new KeyValuePair<string, double>(this.TryFindResource("CageAlarm") as string, count <= 0 ? 0 : count));
            //status[3] = new double[] { (int)Data.Enum.LiftStatus.CageAlarm, count <= 0 ? 0 : count };

            count = 0;
            count = (from ResultData r in list
                     where r.FaultType == (int)Data.Enum.LiftStatus.ConverterAlarm
                     select r).Count();
            valueList.Add(new KeyValuePair<string, double>(this.TryFindResource("ConverterAlarm") as string, count <= 0 ? 0 : count));
            //status[4] = new double[] { (int)Data.Enum.LiftStatus.ConverterAlarm, count <= 0 ? 0 : count };

            this.histogramSeries.DataContext = valueList;
           
            //histogram.HistogramData = status;
            //histogram.TickMarkWidth = 25;
        }

        void btn_print_Click(object sender, RoutedEventArgs e)
        {
            if (!Common.PermissionManager.hasPower((int)Data.Enum.ControlPoints.ExportPrint))
            {
                MessageBox.Show((string)TryFindResource("PermissionDenied"));
                return;
            }
            PrintExcel((IEnumerable<ResultData>)this.faultlogList.ItemsSource);
        }

        void btn_export_Click(object sender, RoutedEventArgs e)
        {
            if (!Common.PermissionManager.hasPower((int)Data.Enum.ControlPoints.ExportPrint))
            {
                MessageBox.Show((string)TryFindResource("PermissionDenied"));
                return;
            }
            msg_title.Text = "正在导出记录";
            msg_shade.Visibility = Visibility.Visible;
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Title = "导出故障统计信息";
            dlg.Filter = "Excel|*.xls";
            Nullable<bool> result = dlg.ShowDialog();
            if (result == true)
            {
                string filename = dlg.FileName;
                try
                {
                    SaveToExcel(filename, (IEnumerable<ResultData>)this.faultlogList.ItemsSource);
                    MessageBox.Show((string)this.TryFindResource("ExportOK"));
                }
                catch { }
            }
            msg_shade.Visibility = Visibility.Hidden;
        }

        private Excel.Application _excelApp = null;
        private Excel.Workbooks _books = null;
        private Excel._Workbook _book = null;
        private Excel.Sheets _sheets = null;
        private Excel._Worksheet _sheet = null;
        private Excel.Range _range = null;
        private Excel.Font _font = null;
        // Optional argument variable
        private object _optionalValue = Missing.Value;

        /// <summary>
        /// 保存到Excel
        /// </summary>
        public void SaveToExcel(string excelName, IEnumerable<ResultData> list)
        {
            try
            {
                if (list != null)
                {
                    if (list.Count() != 0)
                    {
                        Mouse.SetCursor(Cursors.Wait);
                        CreateExcelRef();
                        FillSheet(list);
                        SaveExcel(excelName);
                        Mouse.SetCursor(Cursors.Arrow);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = (string)this.TryFindResource("ExportExcelError");
                Log.WriteError(msg + ex.Message, ex);
                MessageBox.Show(msg);
            }
            finally
            {
                ReleaseCOM(_sheet);
                ReleaseCOM(_sheets);
                ReleaseCOM(_book);
                ReleaseCOM(_books);
                ReleaseCOM(_excelApp);
            }
        }

        public void PrintExcel(IEnumerable<ResultData> list)
        {
            try
            {
                if (list != null)
                {
                    if (list.Count() != 0)
                    {
                        Mouse.SetCursor(Cursors.Wait);
                        CreateExcelRef();
                        FillSheet(list);
                        PrintExcel();
                        Mouse.SetCursor(Cursors.Arrow);

                    }
                }
            }
            catch (Exception ex)
            {
                string msg = (string)this.TryFindResource("ExportExcelError");
                Log.WriteError(msg + ex.Message, ex);
                MessageBox.Show(msg);
            }
            finally
            {
                ReleaseCOM(_sheet);
                ReleaseCOM(_sheets);
                ReleaseCOM(_book);
                ReleaseCOM(_books);
                ReleaseCOM(_excelApp);
            }

        }

        /// <summary>
        /// 创建一个Excel程序实例
        /// </summary>
        private void CreateExcelRef()
        {
            _excelApp = new Excel.Application();
            _books = (Excel.Workbooks)_excelApp.Workbooks;
            _book = (Excel._Workbook)(_books.Add(_optionalValue));
            _sheets = (Excel.Sheets)_book.Worksheets;
            _sheet = (Excel._Worksheet)(_sheets.get_Item(1));

        }

        /// <summary>
        /// 将数据填充到内存Excel的工作表
        /// </summary>
        /// <param name="dataTable"></param>
        private void FillSheet(IEnumerable<ResultData> list)
        {
            object[] header = CreateHeader();
            WriteData(header, list);
        }


        private void WriteData(object[] header, IEnumerable<ResultData> list)
        {
            int count = list.Count();
            object[,] objData = new object[count, header.Length];
            int index = 0;
            foreach (var r in list)
            {
                objData[index, 0] = index + 1;
                objData[index, 1] = r.LiftNum.ToString();
                objData[index, 2] = r.ShortName;
                objData[index, 3] = r.LiftName;
                objData[index, 4] = (string)TryFindResource(((Data.Enum.LiftStatus)r.FaultType).ToString());
                objData[index, 5] = r.JoinDate.ToString("yyyy-MM-dd HH:mm:ss");
                index++;
            }

            AddExcelRows("A2", count, header.Length, objData);
            AutoFitColumns("A1", count + 1, header.Length);
        }

        private object[] CreateHeader()
        {
            List<object> objHeaders = new List<object>();
            objHeaders.Add((string)this.TryFindResource("RowNum"));
            objHeaders.Add((string)this.TryFindResource("LiftNum"));
            objHeaders.Add((string)this.TryFindResource("ShortName"));
            objHeaders.Add((string)this.TryFindResource("LiftSite"));
            objHeaders.Add((string)this.TryFindResource("FaultType"));
            objHeaders.Add((string)this.TryFindResource("JoinDate"));

            var headerToAdd = objHeaders.ToArray();
            //工作表的单元是从“A1”开始
            AddExcelRows("A1", 1, headerToAdd.Length, headerToAdd);
            SetHeaderStyle();

            return headerToAdd;
        }

        private void AutoFitColumns(string startRange, int rowCount, int colCount)
        {
            _range = _sheet.get_Range(startRange, _optionalValue);
            _range = _range.get_Resize(rowCount, colCount);
            _range.Columns.AutoFit();
        }

        /// <summary>
        /// 将表头加粗显示
        /// </summary>
        private void SetHeaderStyle()
        {
            _font = _range.Font;
            _font.Bold = true;
        }

        /// <summary>
        /// 将数据填充到Excel工作表的单元格中
        /// </summary>
        /// <param name="startRange"></param>
        /// <param name="rowCount"></param>
        /// <param name="colCount"></param>
        /// <param name="values"></param>
        private void AddExcelRows(string startRange, int rowCount, int colCount, object values)
        {;
            
            _range = _sheet.get_Range(startRange, _optionalValue);
            _range = _range.get_Resize(rowCount, colCount);
            _range.set_Value(_optionalValue, values);
            _range.ColumnWidth = 150;
            _range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
            _range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;

        }

        /// <summary>
        /// 将内存中Excel保存到本地路径
        /// </summary>
        /// <param name="excelName"></param>
        private void SaveExcel(string excelName)
        {
            _excelApp.Visible = false;
            //保存为Office2003和Office2007都兼容的格式
            _book.SaveAs(excelName, Microsoft.Office.Interop.Excel.XlFileFormat.xlExcel7, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            _excelApp.Quit();
        }

        private void PrintExcel()
        {
            _excelApp.Visible = false;
            Object oMissing = System.Reflection.Missing.Value;  //实例化参数对象 
            try
            {
                _excelApp.ActiveWorkbook.PrintOut(oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
            }
            catch { }
            _excelApp.Quit();
        }

        /// <summary>
        /// 释放COM对象
        /// </summary>
        /// <param name="pObj"></param>
        private void ReleaseCOM(object pObj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(pObj);
            }
            catch
            {
                //throw new Exception("释放资源时发生错误！");
            }
            finally
            {
                pObj = null;
            }
        }


        void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }

        private void sys_button_close_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void sys_button_min_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }
    }

    public class FaultLogItem
    {
        public int LiftNum { get; set; }
        public string LiftName { get; set; }
        public int Fire { get; set; }
        public int Fault { get; set; }
        public int CageAlarm { get; set; }
        public int Earthquake { get; set; }
        public int ConverterAlarm { get; set; }
    }
}
